﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;

namespace ThreadConsole
{
    class Program
    {
        static readonly object _locker = new object();

        /// <summary>
        /// Program.Demo to invoke
        /// </summary>
        static void Demo()
        {
            bool lockTaken = false;
            try
            {
                Monitor.Enter(_locker, ref lockTaken);
                // do you stuff ...
            }
            finally
            {
                if (lockTaken)
                {
                    Monitor.Exit(_locker);
                }
            }
            
            Console.Read();
        }

        private static void ProduceConsume()
        {
            PCQueue q = new PCQueue(2);
            Console.WriteLine("Enqueuing 10 items...");
            for (int i = 0; i < 10; i++)
            {
                int itemNumber = i;      // To avoid the captured variable trap
                q.EnqueueItem(() =>
                {
                    Thread.Sleep(1000);          // Simulate time-consuming work
                    Console.Write(" Task" + itemNumber);
                });
            }
            q.Shutdown(true);
            Console.WriteLine();
            Console.WriteLine("Workers complete!");
        }

        private static void Signalinglocking()
        {
            new Thread(AutoRestEventDemo.Waiter).Start();
            Thread.Sleep(5000);
            AutoRestEventDemo.Notify();

            new Thread(CountdonwEventDemo.SaySomething).Start("I am thread 1");
            new Thread(CountdonwEventDemo.SaySomething).Start("I am thread 2");
            new Thread(CountdonwEventDemo.SaySomething).Start("I am thread 3");
            CountdonwEventDemo.Wait();
            Console.WriteLine("All threads have finished speaking");
        }

        private static void NonExclusivelocking()
        {
            for (int i = 1; i <= 5; i++)
            {
                new Thread(SemaphoreSlimDemo.Enter).Start(i);
            }

            new Thread(ReaderWriterLockSlimDemo.Read).Start();
            new Thread(ReaderWriterLockSlimDemo.Read).Start();
            new Thread(ReaderWriterLockSlimDemo.Read).Start();
            new Thread(ReaderWriterLockSlimDemo.Write).Start("A");
            new Thread(ReaderWriterLockSlimDemo.Write).Start("B");
        }
    }
}
